//	折线图
import React from 'react';
// LineOptions
import { Line } from '@antv/g2plot';
import { data, MIN_MAX } from './mock';
import { getComponentData } from 'src/services/AnalyseManage';
import { WD_TYPE, DL_TYPE, THEME_COLOR } from 'src/pages/AnalyseManage/EditReport/components/EditorDataType/EnumConfig';
import { bigNumberTransform, digitFormat, isNumber } from 'src/libs/utils';
import { ChartService, IProps } from 'src/pages/AnalyseManage/EditReport/components/ChartsType/components/ChartService';
import { CHART_LINK } from 'src/pages/AnalyseManage/EditReport/topics';
import PubSub from 'pubsub-js';

export default class LineChart extends ChartService {
	state = {
		chartEl: null,
		data: data,
		min_max: MIN_MAX,
		eventToken: [],
		dependencies: [],	//	图表联动参数
		isRender: false
	};

	initEvent = async () => {
		const { data, min_max } = await this.getConditionData();
		this.setState( { data: data, min_max: min_max }, () => {
			const line = new Line( this.props.id, this.getConfig( ) );
			line.render();
			this.setState( {
				chartEl: line,
				isRender: true
			} );

			//	数据联动 组装联动参数
			line.on( 'element:click', ( ev ) => {
				if( !this.props.config.mutual.isChainAvailable ) return;

				const intervalElement = ev.target.get( 'element' );
				const data = intervalElement.getModel().data; // 单条数据
				// console.log( data );
				if( Object.prototype.toString.call( data ) === '[object Array]' ) return;
				let dimension = [];

				//	取x轴字段和颜色维度字段
				const tempArray = [
					{
						key: 'chartLineXColumns',
						itemKey: 'name'
					},
					{
						key: 'chartLineColorColumns',
						itemKey: 'category'
					}
				];

				tempArray.forEach( field => {
					let columns = this.props.config.data[field.key];
					if( columns && columns.length > 0 ) {
						dimension = dimension.concat( columns.map( ( item, index ) => {
							return {
								formatType: item.formatType,
								id: [ item.name ],
								quota: item.modelType === WD_TYPE ? 'WD' : 'DL',
								symbol: 'EQ',
								value: [ data[field.itemKey] ]		//	从原数据中找到item，一一对应字段
							};
						} ) );
					}
				} );

				if( dimension.length === 0 ) return;

				PubSub.publish( CHART_LINK, {
					publisherId: this.props.id,
					listenerIds: this.props.config.mutual.chartsChainIds,
					dimension: dimension,
					tableCode: this.props.config.data.tableCode
				} );
			} );
		} );
	};

	getSnapshotBeforeUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{ dependencies: any }> ): any | null {
		let { config } = this.props;
		let changeObj = Object.create( null );
		const prevDataConfig = prevProps.config.data,
			currentDataConfig = config.data;

		//	判断数据字段是否变化了
		if ( JSON.stringify( prevDataConfig.filterFields ) !== JSON.stringify( currentDataConfig.filterFields ) ||
		     JSON.stringify( prevDataConfig.filterConditions ) !== JSON.stringify( currentDataConfig.filterConditions ) ||
			 JSON.stringify( prevDataConfig.chartLineXColumns ) !== JSON.stringify( currentDataConfig.chartLineXColumns ) ||
			 JSON.stringify( prevDataConfig.chartLineYColumns ) !== JSON.stringify( currentDataConfig.chartLineYColumns ) ||
			 JSON.stringify( prevDataConfig.chartLineColorColumns ) !== JSON.stringify( currentDataConfig.chartLineColorColumns ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( prevState.dependencies ) ) {
			changeObj.needDataChange = true;
		}

		if (
			JSON.stringify( prevDataConfig.chartLineYColumnsUnit ) !== JSON.stringify( currentDataConfig.chartLineYColumnsUnit ) ||
			JSON.stringify( prevDataConfig.lineType ) !== JSON.stringify( currentDataConfig.lineType )
		) {
			changeObj.needDataConfigChange = true;
		}

		//	判断样式是否改变
		if ( JSON.stringify( prevProps.config.style ) !== JSON.stringify( config.style ) ) {
			changeObj.needStyleChange = true;
		}

		return changeObj;
	}

	shouldComponentUpdate( nextProps: Readonly<IProps>, nextState: Readonly<{ dependencies: any }>, nextContext: any ): boolean {
		if ( JSON.stringify( nextProps ) !== JSON.stringify( this.props ) ||
			JSON.stringify( this.state.dependencies ) !== JSON.stringify( nextState.dependencies ) ) return true;
		return false;

	}

	async componentDidUpdate( prevProps: Readonly<IProps>, prevState: Readonly<{}>, snapshot?: any ) {

		if ( snapshot.needStyleChange || snapshot.needDataConfigChange ) {
			this.state.chartEl.update( this.getConfig() );
		}

		if ( snapshot.needDataChange ) {
			// 更新折线图的数据
			const { data, min_max } = await this.getConditionData();

			this.setState( { data: data, min_max: min_max }, () => {
				this.state.chartEl.update( this.getConfig() );
				this.state.chartEl.changeData( data );
			} );
		}

	}

	getConfig = ( ): any => {
		let { style, data: dataConfigs } = this.props.config;

		// const getPadding = ( value: number, type: string ) => {
		// 	if ( style.isShowLegend && style.legendPosition === type ) {
		// 		const defaultValue = type === 'left' || type === 'right' ? 100 : 40;
		// 		return value ? value + defaultValue : defaultValue;
		// 	}
		// 	return value ? value : 40;
		// };

		return {
			data: this.state.data,
			xField: 'name',
			yField: 'value',
			seriesField: 'category',
			// 设置轴边距
			appendPadding: [
				style.chartTopPadding || 0,
				style.chartRightPadding || 0,
				style.chartBottomPadding || 0,
				style.chartLeftPadding || 0
			],
			meta: {
				name: {
					alias: style.chartXAxisName || 'name',
				},
				value: {
					alias: style.chartYAxisName || 'value',
					formatter: ( data ) => {
						return data;
					},
				},
			},

			autoFit: true,
			isStack: true,
			padding: 'auto',
			color: ( style.customBlockColor || [] ).map( v => v.color ).concat( THEME_COLOR ),

			legend:
				style.isShowLegend === true
					? {
						position: style.legendPosition,
						itemName: {
							style: {
								fill: style.legendFontColor,
								fontSize: parseInt( style.legendFontSize || 15 ),
								fontFamily: style.legendFontFamily,
								fontWeight: style.legendFontBold ? 'bold' : 'normal',
								fontStyle: style.legendFontItalic ? 'italic' : 'normal',
							},
						},
					  }
					: false,
			tooltip: this.getToolTipConfig( style ),
			xAxis: this.getXAxisConfig( style ),
			yAxis: this.getYAxisConfig( style, dataConfigs ),
			label: this.getLabelConfig( style ),
			// 设置标签
			point: this.getPointOptions( style, dataConfigs ),
			interactions: [ { type: 'element-single-active' } ],
		};
	};

	getYAxisConfig = ( style, dataConfigs ) => {
		return {
			tickCount: 5,
			// tickMethod: ( ...cate ) => {
			// 	console.log( 'cate', cate );
			// 	return [ 100, 200, 300, 400, 500 ];
			// },
			line: style.isShowYLine
				? {
					style: {
						stroke: style.chartLineColor,
					},
				  }
				: null,
			title: style.isShowYLineName
				? {
					style: {
						fontFamily: style.YLineFontFamily || 'SimSun',
						fontSize: parseInt( style.YLineFontSize || 15 ),
						fontWeight: style.YLineFontBold ? 'bold' : 'normal',
						fontStyle: style.YLineFontItalic ? 'italic' : 'normal',
						fill: style.YLineFontColor || '#333',
					},
					position: 'end',
					rotate: 25.15,
				  }
				: null,
			// 网格线样式
			grid: style.isHiddenYGridLine
				? null
				: {
					line: {
						style: {
							stroke: style.chartGridlineColor,
						},
					},
				  },
			// 设置坐标轴文字部分样式
			label: {
				style: style.chartLineDataColor
					? {
						fill: style.chartLineDataColor,
					  }
					: {},
				formatter: ( v ) => {
					const va = bigNumberTransform( v );
					// console.log( va, v );
					return `${va} ${dataConfigs.chartLineYColumnsUnit || ''}`;
				},
			},
		};
	};

	getXAxisConfig = ( style ) => {
		// let fontSize = parseInt( style.XLineFontSize || 15 );
		return {
			tickCount: 5,
			line: style.isShowXLine
				? {
					style: {
						stroke: style.chartLineColor,
					},
				  }
				: null,
			title:
				style.isShowXLine && style.isShowXLineName
					? {
						offset: 30,
						style: {
							fill: style.XLineFontColor || '#333',
							fontFamily: style.XLineFontFamily || 'SimSun',
							fontSize: parseInt( style.XLineFontSize || 15 ),
							fontWeight: style.XLineFontBold ? 'bold' : 'normal',
							fontStyle: style.XLineFontItalic ? 'italic' : 'normal',
						},
					  }
					: null,
			tickLine: style.isShowXLine ? {} : null,
			label: {
				style: style.chartLineDataColor
					? {
						fill: style.chartLineDataColor,
						fontSize: style.isShowXLine ? 12 : 0,
					  }
					: {
						// 设置X轴不显示，设置axis为null不生效，需要设置不显示label,line, tickline
						fontSize: style.isShowXLine ? 12 : 0,
					  },
				rotate: style.chartXAxisLabelTilt ? style.chartXAxisLabelTilt : 0,
			},
		};
	};

	getLabelConfig = ( style ) => {
		const getLabelText = ( category, value, precision, dataUnit ) => {
			return this.getDataByDataUnit( category, value, precision, dataUnit ).value;
		};
		return style.isShowLabelData
			? {
				style: {
					fontFamily: style.labelFontFamily || 'SimSun',
					fontSize: parseInt( style.labeleFontSize || 15 ),
					fontWeight: style.labeleFontBold ? 'bold' : 'normal',
					fontStyle: style.labelFontItalic ? 'italic' : 'normal',
					fill: style.labelFontColor || '#333',
				},
				formatter: ( data, c, d ) => {

					const { value, category, precision = 0, dataUnit = '' } = data;
					if ( style.onlyShowLabelMax && value === this.state.min_max[category].max ) {
						return getLabelText( category, this.state.min_max[category].max, precision, dataUnit );
					} else if ( style.onlyShowLabelMin && value === this.state.min_max[category].min ) {
						return getLabelText( category, this.state.min_max[category].min, precision, dataUnit );
					} else if (
						( style.onlyShowLabelMax && value !== this.state.min_max[category].max ) ||
							( style.onlyShowLabelMin && value !== this.state.min_max[category].min )
					) {
						return null;
					}
					return getLabelText( category, value, precision, dataUnit );
				},
			  }
			: null;
	};

	// 设置数据单位
	getDataByDataUnit = ( category, value, precision = 0, dataUnit = '' ) => {
		value = isNumber( precision ) ? value.toFixed( precision ) : value;		//	小数尾数格式化
		value = digitFormat( value, 3 );				//	千分位格式化

		return {
			name: category,
			value: `${value}${dataUnit}`
		};
	};

	// 设置提示config
	getToolTipConfig = ( style ) => {

		const getToolTipLabel =  ( datum ) => {
			return this.getDataByDataUnit( datum.category, datum.value, datum.precision, datum.dataUnit  );
		};

		return style.isShowToolTip
			? {
				shared: true,
				// 设置toolTip相关样式
				domStyles: {
					'g2-tooltip-list-item': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
					'g2-tooltip-title': {
						fontSize: `${style.tooltipFontSize || '12'}px`,
						color: style.tooltipFontColor,
						fontFamily: style.tooltipFontFamily,
						fontWeight: style.tooltipFontBold ? 'bold' : 'normal',
						fontStyle: style.tooltipFontItalic ? 'italic' : 'normal',
					},
				},

				formatter: ( datum ) => {
					return getToolTipLabel( datum );
				},
				showCrosshairs: true,
				crosshairs: {
					line: {
						style: {
							stroke: style.chartHoverLineColor || 'rgba(33,33,33, 0.5)',
						},
					},
				},
				fields: [ 'name', 'value', 'category', 'precision', 'dataUnit' ]
			  }
			: {
				showContent: false,
				domStyles: null,
				follow: false,
				// showCrosshairs: false
			  };
	};

	// 设置标签样式
	getPointOptions = ( style, dataConfig ) => {
		let config = {
			size: style.chartLabelMarkSize || 5,
			// size: 0,
			shape: style.chartLabelMarkType ? ( style.chartLabelMarkType === 'hollowCircle' ? 'hollow-circle' : style.chartLabelMarkType ) : 'circle',
			style: {
				fill: '',
				stroke: '',
				lineWidth: 0,
				fillOpacity: dataConfig.lineType === 'basic' ? 0 : 1
			},

			color: style.chartLabelMarkColor,
		};
		// 如果是空心圆需要填充白色
		if ( style.chartLabelMarkType === 'hollowCircle' ) {
			config.style.fill = 'white';
			// config.style.stroke = '#5B8FF9'; // inherit
			config.style.lineWidth = 2;
		}

		//	只有设置了数据点，才可以点击联动，所以在basic下，设置数据点为透明
		return config;
	};


	// 获取折线图的数据
	async getConditionData() {
		const { data: dataConfigs } = this.props.config;
		if (
			dataConfigs.chartLineXColumns &&
			dataConfigs.chartLineXColumns.length > 0 &&
			dataConfigs.chartLineYColumns &&
			dataConfigs.chartLineYColumns.length > 0
		) {
			const itemInfo = ( v, orderType?, desc? ) => {
				return {
					aggregateType: v.modelType === DL_TYPE ? v.aggregateType : '', //	度量的聚合类型
					formatType: v.modelType === WD_TYPE ? v.formatType : '', // 维度的聚合类型v.
					alias: v.title.trim(),
					dataType: v.dataType,
					frontendId: '',
					id: v.name,
					orderType: v.modelType === DL_TYPE && !v.orderType ? 'ASC' : v.orderType, // 排序方式
					quota: v.modelType === WD_TYPE ? 'WD' : 'DL',
					symbol: '',
					type: v.type,
					value: '',
					dataUnit: v.dataUnit || '',
					precision: v.precision
				};
			};
			const x = dataConfigs.chartLineXColumns.map( ( v ) => {
				return itemInfo( v );
			} );

			const y = dataConfigs.chartLineYColumns.map( ( v ) => {
				return itemInfo( v );
			} );

			const category = dataConfigs.chartLineColorColumns
				? dataConfigs.chartLineColorColumns.map( ( v ) => {
					return itemInfo( v );
				  } )
				: [];

			// 内部筛选 condition
			const filterFieldCondition = this.props.config.data.filterFields
				? this.props.config.data.filterFields.map( ( v ) => v.filterConditions ).flat()
				: [];

			// 筛选组件的 condition
			let filterCompConditions = this.props.config.data.filterConditions || {};
			let newFilterCompConditions = [];
			Object.keys( filterCompConditions ).forEach( ( key ) => {
				newFilterCompConditions = newFilterCompConditions.concat( filterCompConditions[key] );
			} );

			const request = {
				dataConfig: {
					dataModel: {
						pageId: this.props.pageId,
						tableName: this.props.config.data.tableCode,
						x: x,
						y: y,
						category: category,
						conditions: filterFieldCondition.concat( this.state.dependencies, newFilterCompConditions ),
					},
					needAutoRefresh: true,
					tableType: 'simple',
				},
				type: 'line',
				tenantCode: this.props.tenantCode
			};

			let pageResponse = await getComponentData( request );
			if ( pageResponse.data && pageResponse.data.success ) {
				const { extra, rows = [], } = pageResponse.data.data;

				return { data: rows, min_max: extra && extra.maxmin };
			}
		}

		return { data, min_max: MIN_MAX };
	}

	render() {
		return <div id={this.props.id} style={{ height: '100%' }}></div>;
	}
}
